﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.ServiceModel;

namespace RentIt06
{
    public class AdminSession : IAdminSession
    {
        private bool loggedIn;

        public Account Login(string email, string password) {
            var dbResult = from u in new db.DataMapDataContext().Users
                           where u.email == email
                              && u.password == Account.hash(password, email)
                              && u.role == PermissionGroup.Admin.ToString()
                           select u;
            if (dbResult.Any())
            {
                loggedIn = true;
                return new Account(dbResult.First());
            }

            throw new FaultException(new FaultReason("Wrong password, email or user has insufficent access"), new FaultCode("401"));
        }

        private void checkIfLoggedIn()
        {
            if (!loggedIn) throw new FaultException("You are not logged in");
        }

        public Account ReadAccountEmail(string email) {
            checkIfLoggedIn();
            var result = from u in new db.DataMapDataContext().Users
                         where u.email == email 
                         select u;
            if (result.Any()) return new Account(result.First());
            throw new FaultException(new FaultReason("No account was found"), new FaultCode("404"));
        }

        public Account ReadAccountId(int id) {
            checkIfLoggedIn();
            var result = from u in new db.DataMapDataContext().Users
                         where u.id == id
                         select u;
            if (result.Any()) return new Account(result.First());
            throw new FaultException(new FaultReason("No account was found"), new FaultCode("404"));
        }

        public List<Account> ReadAllAccounts() {
            checkIfLoggedIn();
            return (from u in new db.DataMapDataContext().Users
                    select u).Select(u => new Account(u)).ToList();
        }
        
        /*
        private Account ReadAccount(Func<db.User, bool> predicate) {
            var result = from u in new db.DataMapDataContext().Users
                         where predicate(u)
                         select u;
            if (result.Count() > 0) return new Account(result.First());
            throw new FaultException(new FaultReason("No account was found"), new FaultCode("404"));
        }

        public Account ReadAccountEmail(string email) {
            return ReadAccount(user => user.email == email);
        }
        
        public Account ReadAccountId(int id) {
            return ReadAccount(user => user.id == id);
        }
        */

        public void DeleteAccount(int id) {
            checkIfLoggedIn();
            var dbSession = new db.DataMapDataContext();
            var dbResult = from u in dbSession.Users
                           where u.id == id
                           select u;
            if (!dbResult.Any())
            {
                throw new FaultException(new FaultReason("No account with id " + id + " found."), new FaultCode("404"));
            }
            dbSession.Users.DeleteOnSubmit(dbResult.First());
            dbSession.SubmitChanges();
        }

        public void ChangeAccountAccessLevel(int id, PermissionGroup accessLevel) {
            checkIfLoggedIn();
            var dbSession = new db.DataMapDataContext();
            var dbResult = from u in dbSession.Users
                           where u.id == id
                           select u;
            if (!dbResult.Any())
            {
                throw new FaultException(new FaultReason("No account with id " + id + " found."), new FaultCode("404"));
            }
            var acc = dbResult.First();
            acc.role = accessLevel.ToString();
            dbSession.SubmitChanges();
        }

        public void Logout() {
            // DONE!
        }
    }
}
